package com.wo.cloud.config;

import com.wo.cloud.filter.TokenAuthFilter;
import com.wo.cloud.filter.TokenLoginFilter;
import com.wo.cloud.security.DefaultPasswordEncoder;
import com.wo.cloud.security.TokenLogoutHandler;
import com.wo.cloud.security.TokenManager;
import com.wo.cloud.security.UnauthorizationEntryPoint;
import com.wo.cloud.service.UserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.annotation.Resource;

/**
 * @author liry
 * @version 1.0
 * @date Created on 2021/4/19 10:15
 * Description:
 */

@Configuration
public class TokenSecurityConfig extends WebSecurityConfigurerAdapter {

    //    private AuthenticationManager authenticationManager;
    private UserDetailServiceImpl userDetailServiceImpl;
    private TokenManager tokenManager;
    @Resource
    private RedisTemplate redisTemplate;
    private DefaultPasswordEncoder defaultPasswordEncoder;

    @Autowired
    public TokenSecurityConfig(UserDetailServiceImpl userDetailServiceImpl,
                               TokenManager tokenManager,
                               DefaultPasswordEncoder passwordEncoder) {
        this.userDetailServiceImpl = userDetailServiceImpl;
        this.tokenManager = tokenManager;
        this.defaultPasswordEncoder = passwordEncoder;
    }

    /**
     * http过滤配置配置
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling()
                .authenticationEntryPoint(new UnauthorizationEntryPoint())
                .and()
                .csrf().disable().authorizeRequests().anyRequest().authenticated()
                .and()
                .logout().logoutUrl("/admin/logout").addLogoutHandler(new TokenLogoutHandler(redisTemplate, tokenManager))
                .and()
                .addFilter(new TokenLoginFilter(redisTemplate, tokenManager, authenticationManager()))
                .addFilter(new TokenAuthFilter(authenticationManager(), redisTemplate, tokenManager))
                .httpBasic();
    }

    /**
     * 认证处理, 调用userDetailService和加密处理
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailServiceImpl).passwordEncoder(defaultPasswordEncoder);
    }

    /**
     * 不进行认证可直接访问的配置
     *
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/api/**");
    }
}
